using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using System.Diagnostics;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

/// <summary>
/// 日志系统优化和最佳实践
/// Microsoft.Extensions.Logging + Serilog 混合架构的高级优化
/// </summary>
public static class LoggingOptimizations
{
    /// <summary>
    /// 添加高性能日志过滤器
    /// 减少不必要的日志开销，特别是在生产环境中
    /// </summary>
    /// <param name="services">服务集合</param>
    public static IServiceCollection AddHighPerformanceLoggingFilters(this IServiceCollection services)
    {
        services.Configure<LoggerFilterOptions>(options =>
        {
            // 过滤掉 Entity Framework 的调试信息（生产环境）
            options.AddFilter("Microsoft.EntityFrameworkCore", LogLevel.Warning);
            
            // 过滤掉 ASP.NET Core 的详细信息
            options.AddFilter("Microsoft.AspNetCore", LogLevel.Information);
            
            // 系统相关日志只记录警告以上
            options.AddFilter("System", LogLevel.Warning);
            
            // HTTP 客户端请求只记录错误
            options.AddFilter("System.Net.Http.HttpClient", LogLevel.Error);
            
            // 保留应用程序日志的所有级别
            options.AddFilter("JGSY.CMS.LowCode.Platform", LogLevel.Debug);
        });

        return services;
    }

    /// <summary>
    /// 添加日志性能监控
    /// 监控日志系统本身的性能
    /// </summary>
    /// <param name="services">服务集合</param>
    public static IServiceCollection AddLoggingPerformanceMonitoring(this IServiceCollection services)
    {
        services.AddSingleton<LoggingPerformanceMonitor>();
        return services;
    }

    /// <summary>
    /// 配置结构化日志最佳实践
    /// </summary>
    /// <param name="services">服务集合</param>
    public static IServiceCollection AddStructuredLoggingOptimizations(this IServiceCollection services)
    {
        // 添加日志上下文增强器
        services.AddScoped<ILogContextEnricher, LogContextEnricher>();
        
        // 添加敏感数据脱敏器
        services.AddSingleton<IDataSanitizer, DataSanitizer>();
        
        return services;
    }
}

/// <summary>
/// 日志性能监控器
/// </summary>
public class LoggingPerformanceMonitor
{
    private readonly Stopwatch _stopwatch = new();
    private long _logCount = 0;
    private long _totalLogTime = 0;

    /// <summary>
    /// 开始监控日志操作
    /// </summary>
    public IDisposable StartMonitoring()
    {
        return new LogMonitoringScope(this);
    }

    /// <summary>
    /// 记录日志性能指标
    /// </summary>
    /// <param name="elapsedTicks">耗时tick数</param>
    public void RecordLogPerformance(long elapsedTicks)
    {
        Interlocked.Increment(ref _logCount);
        Interlocked.Add(ref _totalLogTime, elapsedTicks);
    }

    /// <summary>
    /// 获取性能统计
    /// </summary>
    public (long LogCount, double AverageTimeMs) GetStatistics()
    {
        var count = Interlocked.Read(ref _logCount);
        var totalTime = Interlocked.Read(ref _totalLogTime);
        
        var averageTimeMs = count > 0 
            ? (double)totalTime / count / TimeSpan.TicksPerMillisecond 
            : 0;
            
        return (count, averageTimeMs);
    }

    private class LogMonitoringScope : IDisposable
    {
        private readonly LoggingPerformanceMonitor _monitor;
        private readonly long _startTicks;

        public LogMonitoringScope(LoggingPerformanceMonitor monitor)
        {
            _monitor = monitor;
            _startTicks = Stopwatch.GetTimestamp();
        }

        public void Dispose()
        {
            var elapsedTicks = Stopwatch.GetTimestamp() - _startTicks;
            _monitor.RecordLogPerformance(elapsedTicks);
        }
    }
}

/// <summary>
/// 日志上下文增强器接口
/// </summary>
public interface ILogContextEnricher
{
    /// <summary>
    /// 为日志添加上下文信息
    /// </summary>
    /// <param name="context">上下文字典</param>
    void EnrichContext(Dictionary<string, object> context);
}

/// <summary>
/// 日志上下文增强器实现
/// </summary>
public class LogContextEnricher : ILogContextEnricher
{
    private readonly IHttpContextAccessor? _httpContextAccessor;

    public LogContextEnricher(IHttpContextAccessor? httpContextAccessor = null)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    /// <summary>
    /// 为日志添加丰富的上下文信息
    /// </summary>
    public void EnrichContext(Dictionary<string, object> context)
    {
        // 添加机器信息
        context["MachineName"] = Environment.MachineName;
        context["ProcessId"] = Environment.ProcessId;
        context["ThreadId"] = Environment.CurrentManagedThreadId;
        
        // 添加时间戳
        context["UtcTimestamp"] = DateTime.UtcNow;
        
        // 添加 HTTP 上下文信息（如果可用）
        var httpContext = _httpContextAccessor?.HttpContext;
        if (httpContext != null)
        {
            context["RequestId"] = httpContext.TraceIdentifier;
            context["UserAgent"] = httpContext.Request.Headers.UserAgent.ToString();
            context["RemoteIpAddress"] = httpContext.Connection.RemoteIpAddress?.ToString() ?? "Unknown";
            
            // 添加用户信息（如果已认证）
            if (httpContext.User.Identity?.IsAuthenticated == true)
            {
                context["UserId"] = httpContext.User.Identity.Name ?? "Unknown";
            }
        }
        
        // 添加应用程序信息
        context["ApplicationName"] = "JGSY.CMS.LowCode.Platform";
        context["Environment"] = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Unknown";
    }
}

/// <summary>
/// 敏感数据脱敏器接口
/// </summary>
public interface IDataSanitizer
{
    /// <summary>
    /// 脱敏敏感数据
    /// </summary>
    /// <param name="data">原始数据</param>
    /// <returns>脱敏后的数据</returns>
    object SanitizeData(object? data);
}

/// <summary>
/// 敏感数据脱敏器实现
/// </summary>
public class DataSanitizer : IDataSanitizer
{
    private static readonly string[] SensitiveFields = 
    {
        "password", "pwd", "secret", "key", "token", "authorization",
        "credit", "card", "ssn", "social", "phone", "email", "address"
    };

    /// <summary>
    /// 对敏感数据进行脱敏处理
    /// </summary>
    public object SanitizeData(object? data)
    {
        if (data == null) return "";

        // 处理字符串类型
        if (data is string stringData)
        {
            return SanitizeString(stringData);
        }

        // 处理字典类型
    if (data is Dictionary<string, object> dictionary)
        {
            var sanitized = new Dictionary<string, object>();
            foreach (var kvp in dictionary)
            {
                var key = kvp.Key.ToLowerInvariant();
                if (SensitiveFields.Any(field => key.Contains(field)))
                {
                    sanitized[kvp.Key] = "***REDACTED***";
                }
                else
                {
            sanitized[kvp.Key] = SanitizeData(kvp.Value);
                }
            }
            return sanitized;
        }

        // 处理复杂对象（使用反射）
        var type = data.GetType();
        if (type.IsClass && type != typeof(string))
        {
            // 这里可以扩展复杂对象的脱敏逻辑
            return data.ToString() ?? "Object";
        }

    return data;
    }

    private static string SanitizeString(string input)
    {
        if (string.IsNullOrEmpty(input)) return input;
        
        // 简单的字符串脱敏：保留前后几个字符，中间用*替代
        if (input.Length <= 4) return "****";
        
        var start = input.Substring(0, 2);
        var end = input.Substring(input.Length - 2);
        var middle = new string('*', Math.Max(2, input.Length - 4));
        
        return start + middle + end;
    }
}

/// <summary>
/// 日志扩展方法 - 高性能版本
/// </summary>
public static class HighPerformanceLoggingExtensions
{
    /// <summary>
    /// 高性能结构化日志记录
    /// 使用编译时优化和条件检查
    /// </summary>
    [Conditional("DEBUG")]
    public static void LogDebugHighPerformance<T>(this Microsoft.Extensions.Logging.ILogger<T> logger, 
        string message, params object[] args)
    {
        if (logger.IsEnabled(LogLevel.Debug))
        {
            logger.LogDebug(message, args);
        }
    }

    /// <summary>
    /// 安全的用户操作日志（自动脱敏）
    /// </summary>
    public static void LogUserActionSafe<T>(this Microsoft.Extensions.Logging.ILogger<T> logger, 
        IDataSanitizer sanitizer, string userId, string action, object? details = null)
    {
        var sanitizedDetails = details != null ? sanitizer.SanitizeData(details) : null;
        logger.LogInformation("安全用户操作: {UserId} 执行了 {Action}，详细信息: {@Details}", 
            userId, action, sanitizedDetails);
    }

    /// <summary>
    /// 批量日志记录（高性能）
    /// </summary>
    public static void LogBatch<T>(this Microsoft.Extensions.Logging.ILogger<T> logger, 
        LogLevel level, IEnumerable<(string Message, object[] Args)> logEntries)
    {
        if (!logger.IsEnabled(level)) return;

        foreach (var (message, args) in logEntries)
        {
            logger.Log(level, message, args);
        }
    }
}
